package com.tanhua.app.service;

import cn.hutool.core.util.PageUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.api.service.UserInfoApi;
import com.tanhua.api.service.VideoApi;
import com.tanhua.app.Interceptor.UserHolder;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.pojo.UserInfo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VideoVo;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class SmallVideosService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @DubboReference
    private VideoApi videoApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    // 发布视频
    public void saveVideo(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {

        // oos文件上传视频封面图片
        String imgUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());

        // 使用FastDFS上传视频
        // 获取扩展名
        String exitName = videoFile.getOriginalFilename().substring(videoFile.getOriginalFilename().lastIndexOf(".") + 1);

        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), exitName, null);

        String fullPath = storePath.getFullPath();
        String videoUrl = webServer.getWebServerUrl() + fullPath;

        // 封装对象
        Video video = new Video();
        video.setCreated(System.currentTimeMillis());
        video.setUserId(UserHolder.getUserId());
        video.setPicUrl(imgUrl);
        video.setVideoUrl(videoUrl);

        // 保存
        String id = videoApi.save(video);
    }

    // 小视频列表
    @Cacheable(value = "videos",
        key = "T(com.tanhua.app.Interceptor.UserHolder).getUserId() + '_' + #page + '_' + #pagesize"
    )
    public PageResult<VideoVo> findPageVideos(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();
        // 获取redis中的推荐视频的vid
        String key = Constants.VIDEO_LIKE_HASHKEY + userId;
        String redisValue = redisTemplate.opsForValue().get(key);

        // 判断redis中是否有数据
        List<Video> videoList = new ArrayList<>();
        int redisPages = 0;
        if (StringUtils.isNotEmpty(redisValue)) {
            // 如果redis的数据存在，根据vid获取数据
            String[] arr = redisValue.split(",");
            if ((page - 1) * pagesize < arr.length) {
                List<Long> vids = Arrays.stream(arr)
                        .map(Long::parseLong)
                        .skip((page - 1) * pagesize)
                        .limit(pagesize)
                        .collect(Collectors.toList());

                // 根据vids查询推荐视频数据
                videoList = videoApi.findPageByVid(vids);

            }

            redisPages = PageUtil.totalPage(arr.length, pagesize);

        }

        if (page > redisPages) {
            // 获取所有的小视频数据
            videoList = videoApi.findPageAll((page - redisPages), pagesize);
        }

        // 获取所有的用户id
        List<Long> userIds = videoList.stream().map(Video::getUserId).collect(Collectors.toList());

        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds).stream()
                .collect(Collectors.toMap(UserInfo::getId, Function.identity()));

        // 封装数据
        List<VideoVo> list = new ArrayList<>();
        for (Video video : videoList) {
            UserInfo userInfo = map.get(video.getUserId());
            if (userInfo != null) {
                VideoVo vo = VideoVo.init(userInfo, video);

                list.add(vo);
            }
        }


        return new PageResult<>(page, pagesize, 0L, list);
    }
}
